

/*
 * AtomPanel.java
 *
 * Created on 11.11.2009, 15:56:20
 */

package pabudr_se;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import javax.swing.event.MouseInputListener;


/**
 *
 * @author hendricb
 */
public class AtomPanel extends javax.swing.JPanel implements MouseInputListener {

    
    private static final boolean DEBUG = DebugStatus.DEBUG;
    //private ArrayList<Barrier> list_barrieren;
    //private ArrayList<Atom> list_atome;
    private BufferedImage image = null;
    private Settings settings = new Settings();
    public boolean isRunning = false;
    private boolean clear = false;


    /** Creates new form AtomPanel */
    private AtomPanel() {
        super();
        initComponents();
        settings = new Settings();
        this.addMouseListener(this);
       // list_atome = settings.list_atome;
       // list_barrieren = settings.list_barrieren;
        
        // richtigen image typ einfuegen
        // image = new BufferedImage(this.WIDTH, this.HEIGHT,0);

        //list_atome = new ArrayList<Atom>();        
        
    }
    // TODO
    // fehler dass image kleiner als panel liegt hier begraben
    // evtl ist wahre panelgroesse erst nach dem 1. paint aufruf bekannt
    @Override
    public void paint(Graphics _g) {
        super.paint(_g);
        Graphics2D g_image;
        if (image == null)
        {
            if(DEBUG)
            {
                //
                System.out.println("AtomPanel groesse beim aufruf von paint = image groesse");
                System.out.println("width\t=\t"+this.getSize().width);
                System.out.println("height\t=\t"+this.getSize().height);
                //System.out.println("Test AtomPanel.getWidth()\t.getHeight()");
               // System.out.println("width\t=\t"+this.getSize().width);
                //System.out.println("height\t=\t"+this.getSize().height);




            }
            
            image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
            g_image = image.createGraphics();
            if(DEBUG) System.out.println("Farbe fuer Image = "+ this.getBackground());
            g_image.setColor(this.getBackground());            
            g_image.clearRect(0, 0, image.getWidth(), image.getHeight());
        } else {
            g_image = image.createGraphics();
        }
        Graphics2D g = (Graphics2D)_g;
        
        //g.clearRect(0, 0, this.getWidth(), this.getHeight());
        g.drawImage(image, null, 0, 0);

        for( Atom at : settings.list_atome )
        {
            final Color atColor = at.getFarbe();
                        
            //ein markiertes Atom soll ausgefuellt gemalt werden und auch ins Image kommen
            if (at.isMarked) {
                g.setColor(atColor);
                g.fill(at);
                g.setColor(Color.BLACK);
                g.draw(at);
                g_image.setColor( atColor );
                g_image.fill(at);
            }
            //ansonsten soll nur sein Umkreis gemalt werden
            else {
                g.setColor( atColor );
                g.draw(at);
            }
        }

        for( Barrier b : settings.list_barrieren )
        {
            g.setColor(Color.WHITE);
            g.draw(b);
        }
    }



    
    //evtl ÃƒÂ¼berflÃƒÂ¼ssig wegen setSEttingss
    ArrayList<Barrier> getList_barrieren() {
        return settings.list_barrieren;
    }
    
    //evtl ÃƒÂ¼berflÃƒÂ¼ssig wegen setSEttings
    ArrayList<Atom> getList_atome() {
        return settings.list_atome;
    }

    Settings getSettings() {
        //Dimension aktualisieren
        settings.dimension = this.getSize(settings.dimension);
        return settings;
    }



    //evtl ÃƒÂ¼berflÃƒÂ¼ssig wegen setSEttings
    void setList_atome(ArrayList<Atom> list_atome) {
        //this.list_atome = list_atome;
        this.settings.list_atome = list_atome;
    }

    void setSettings(Settings settings) {
        this.settings = settings;
    }

    //soll ÃƒÂ¼ber stop button aufgerufen werden
    //und ein leeres panel darstellen
    void clearView(){
        if( DEBUG )
        {
            System.out.println("AtomPanel wird geleert");
            System.out.println("Atom und Barrierlisten mit leerer liste ueberschreiben");
        }
        this.settings.list_atome = new ArrayList<Atom>();
        this.settings.list_barrieren = new ArrayList<Barrier>();
        this.image = null;
        this.repaint();
        //clear = true;
        //this.repaint();
        //clear = false;
    }

    BufferedImage getImage()
    {
        return image;
    }


     /**
	 * erzeugt eine Collection von zufÃ¯Â¿Â½lligen Atomen
	 * @param count Anzahl
	 * @param maxX
	 * @param maxY
	 * @param absMaxVx
	 * @param absMaxVy
	 * @param maxRad
	 * @param maxMass
	 * @return
	 */
	public static Collection<Atom> createRandomAtoms(int count,
            float maxX, float maxY, float absMaxVx, float absMaxVy,
            float maxRad, float minRad, float maxMass, float minMass)
	{
            Random r = new Random(System.currentTimeMillis());
            Collection<Atom> coll = new ArrayList<Atom>(count);
            float rad; //den Radius vorher bestimmen, dass die Position im Rahmen bleibt
            maxX -= maxRad;
            maxY -= maxRad;

            for (int i = 0; i < count; ++i)
            {
                rad = r.nextFloat() * (maxRad - minRad) + minRad;
                coll.add(
                    new Atom(
                        r.nextFloat() * (maxX - 4*rad) + rad,
                        r.nextFloat() * (maxY - 4*rad) + rad,
                        r.nextFloat() * absMaxVx * (r.nextBoolean() ? 1 : -1),
                        r.nextFloat() * absMaxVy * (r.nextBoolean() ? 1 : -1),
                        r.nextFloat() * (maxMass - minMass) + minMass,
                        rad,
                        new Color(r.nextInt())
                        )
                    );
            }
            return coll;
	}



    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(AtomPanel.class);
        setBackground(resourceMap.getColor("Form.background")); // NOI18N
        setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 10));
        setForeground(resourceMap.getColor("Form.foreground")); // NOI18N
        setName("Form"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 380, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 280, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    private static volatile AtomPanel existing = null;

    //instance getter
    public static AtomPanel getAtomPanel()
    {
        if(existing == null)
        {
            synchronized(AtomPanel.class)
            {
                return existing = new AtomPanel();
            }
        }else
        {
            return existing;
        }
                                  
    }

    /**
     * setzt das Image auf null
     */
    void clearImage()
    {
        this.image = null;
    }

    public void mouseClicked(MouseEvent e) {
        if(DEBUG)
        {
                System.out.println("AtomPanel size nach erstellung der Instanze und GUI");
                System.out.println("width\t=\t"+this.getSize().width);
                System.out.println("height\t=\t"+this.getSize().height);
        }
        if (isRunning) return;
        final Atom a = findAtomByPunkt(e.getPoint());
        if (a == null) return;
        final int button = e.getButton();
        if (button == MouseEvent.BUTTON1)
        {
            a.isMarked = !a.isMarked;
        }
        else if (button == MouseEvent.BUTTON2 || button == MouseEvent.BUTTON3)
        {
            settings.list_atome.remove(a);
        }
        this.repaint();
    }

    private final Atom findAtomByPunkt(final Point2D punkt)
    {
        for (Atom a : settings.list_atome)
        {
            if (a.contains(punkt))
            {
                return a;
            }
        }
        return null;
    }

    public void mousePressed(MouseEvent e) { }

    public void mouseReleased(MouseEvent e) { }

    public void mouseEntered(MouseEvent e) { }

    public void mouseExited(MouseEvent e) { }

    public void mouseDragged(MouseEvent e) { }

    public void mouseMoved(MouseEvent e) { }


}
